<!DOCTYPE HTML>
<html>
 <head>
  <link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
  <script src="qunit.js"></script>
  <script src="lscache.js"></script>
  <script>
module('lscache', {
  setup: function() {
    // Reset localStorage before each test
    try {
      localStorage.clear();
    } catch(e) {}
  },
  teardown: function() {
    // Reset localStorage after each test
    try {
      localStorage.clear();
    } catch(e) {}
  }
});

test('Testing set() and get() with string', function() {
  var key = 'thekey';
  var value = 'thevalue'
  lscache.set(key, value, 1);
  if (lscache.supported()) {
    equals(lscache.get(key), value, 'We expect value to be ' + value);
  } else {
    equals(lscache.get(key), null, 'We expect null value');
  }
});

if (lscache.supported()) {

test('Testing set() with non-string values', function() {
  var key, value;

  key = 'numberkey';
  value = 2;
  lscache.set(key, value, 3);
  equals(lscache.get(key)+1, value+1, 'We expect incremented value to be ' + (value+1));

  key = 'arraykey';
  value = ['a', 'b', 'c'];
  lscache.set(key, value, 3);
  equals(lscache.get(key).length, value.length, 'We expect array to have length ' + value.length);

  key = 'objectkey';
  value = {'name': 'Pamela', 'age': 26};
  lscache.set(key, value, 3);
  equals(lscache.get(key).name, value.name, 'We expect name to be ' + value.name);
});

test('Testing remove()', function() {
  var key = 'thekey';
  lscache.set(key, 'bla', 2);
  lscache.remove(key);
  equals(lscache.get(key), null, 'We expect value to be null');
});

test('Testing flush()', function() {
  localStorage.setItem('outside-cache', 'not part of lscache');
  var key = 'thekey';
  lscache.set(key, 'bla', 100);
  lscache.flush();
  equals(lscache.get(key), null, 'We expect flushed value to be null');
  equals(localStorage.getItem('outside-cache'), 'not part of lscache', 'We expect localStorage value to still persist');
});

test('Testing setBucket()', function() {
  var key = 'thekey';
  var value1 = 'awesome';
  var value2 = 'awesomer';
  var bucketName = 'BUCKETONE';
      
  lscache.set(key, value1, 1);
  lscache.setBucket(bucketName);
  lscache.set(key, value2, 1);
  
  equals(lscache.get(key), value2, 'We expect "' + value2 + '" to be returned for the current bucket: ' + bucketName);
  lscache.flush();
  equals(lscache.get(key), null, 'We expect "' + value2 + '" to be flushed for the current bucket');
  lscache.resetBucket();
  equals(lscache.get(key), value1, 'We expect "' + value1 + '", the non-bucket value, to persist');
});

test('Testing quota exceeding', function() {
  var key = 'thekey';

  // Figure out this browser's localStorage limit -
  // Chrome is around 2.6 mil, for example
  var stringLength = 10000;
  var longString = (new Array(stringLength+1)).join('s');
  var num = 0;
  while(num < 10000) {
    try {
      localStorage.setItem(key + num, longString);
      num++;
    } catch (e) {
      break;
    }
  }
  localStorage.clear();
  // Now add enough to go over the limit
  var approxLimit = num * stringLength;
  var numKeys = Math.ceil(approxLimit/(stringLength+8)) + 1;
  for (var i = 0; i <= numKeys; i++) {
    var currentKey = key + i;
    lscache.set(currentKey, longString, i+1);
  }
  // Test that last-to-expire is still there
  equals(lscache.get(currentKey), longString, 'We expect newest value to still be there');
  // Test that the first-to-expire is kicked out
  equals(lscache.get(key + '0'), null, 'We expect oldest value to be kicked out (null)');

  // Test trying to add something thats bigger than previous items,
  // check that it is successfully added (requires removal of multiple keys)
  var veryLongString = longString + longString;
  lscache.set(key + 'long', veryLongString, i+1);
  equals(lscache.get(key + 'long'), veryLongString, 'We expect long string to get stored');

  // Try the same with no expiry times
  localStorage.clear();
  for (var i = 0; i <= numKeys; i++) {
    var currentKey = key + i;
    lscache.set(currentKey, longString);
  }
  // Test that latest added is still there
  equals(lscache.get(currentKey), longString, 'We expect value to be set');
});

// We do this test last since it must wait 1 minute
asyncTest('Testing set() and get() with string and expiration', 1, function() {

  var key = 'thekey';
  var value = 'thevalue';
  var minutes = 1;
  lscache.set(key, value, minutes);
  setTimeout(function() {
    equals(lscache.get(key), null, 'We expect value to be null');
    start();
  }, 1000*60*minutes);
});

asyncTest('Testing set() and get() with string and expiration in a different bucket', 2, function() {

  var key = 'thekey';
  var value1 = 'thevalue1';
  var value2 = 'thevalue2';
  var minutes = 1;
  var bucket = 'newbucket';
  lscache.set(key, value1, minutes * 2);
  lscache.setBucket(bucket);
  lscache.set(key, value2, minutes);
  setTimeout(function() {
    equals(lscache.get(key), null, 'We expect value to be null for the bucket: ' + bucket);
    lscache.resetBucket();
    equals(lscache.get(key), value1, 'We expect value to be ' + value1 + ' for the base bucket.');
    start();
  }, 1000*60*minutes);
});

}

  </script>
 </head>
 <body>
  <h1 id="qunit-header">QUnit lscache tests</h1>
  <h2 id="qunit-banner"></h2>
  <div id="qunit-testrunner-toolbar"></div>
  <h2 id="qunit-userAgent"></h2>
  <ol id="qunit-tests"></ol>
  <div id="qunit-fixture">test markup, will be hidden</div>
 </body>
</html>
